package com.study.example.gameserver.serverinfo.service;

import com.sparrow.common.util.JsonUtil;
import com.study.example.gameserver.serverinfo.entity.ServerInfo;
import com.study.example.gameserver.serverinfo.entity.ServerInfoId;
import com.sparrow.cache.entity.EntityCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class ServerInfoService {
    @Autowired
    private EntityCache<ServerInfoId, ServerInfo> entityCache;
    /**
     * 二级缓存
     */
    private final ConcurrentHashMap<ServerInfoId, Object> jsonObjectCache = new ConcurrentHashMap<>();

    public String getValue(int serverId, String key) {
        ServerInfo info = entityCache.get(new ServerInfoId(serverId, key));
        return info != null ? info.getValue() : null;
    }

    public void setValue(int serverId, String key, String value) {
        ServerInfoId id = new ServerInfoId(serverId, key);
        ServerInfo info = entityCache.getOrCreate(id, e -> {
            e.setServerId(serverId);
            e.setInfoKey(key);
        });
        info.setValue(value);
        info.update();
    }

    @SuppressWarnings("unchecked")
    public <T> T getObject(int serverId, String key, Class<T> clazz) {
        ServerInfoId id = new ServerInfoId(serverId, key);
        try {
            Object cached = jsonObjectCache.computeIfAbsent(id, k -> {
                ServerInfo info = entityCache.get(k);
                if (info == null || info.getValue() == null || info.getValue().isEmpty()) {
                    try {
                        // 创建新实例
                        T newInstance = clazz.getDeclaredConstructor().newInstance();
                        // 持久化默认对象（JSON）
                        saveObject(serverId, key, newInstance);
                        return newInstance;
                    } catch (InstantiationException | IllegalAccessException |
                             InvocationTargetException | NoSuchMethodException ex) {
                        throw new RuntimeException("Failed to create new instance of " + clazz, ex);
                    }
                }
                // 解析缓存中的JSON字符串
                return JsonUtil.parse(info.getValue(), clazz);
            });
            return (T) cached;
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void saveObject(int serverId, String key, Object obj) {
        String json = JsonUtil.toJSON(obj);
        setValue(serverId, key, json);
    }
}

